package com.eascs.web.o2o.scheduler.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.eascs.account.api.IAccountService;
import com.eascs.account.api.constants.enums.AccountType;
import com.eascs.account.api.constants.enums.SourceType;
import com.eascs.account.api.vo.CreateAccountParamVO;
import com.eascs.app.dao.PageResult;
import com.eascs.app.dao.SqlPageQuery;
import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.app.runtime.RuntimeSetting;
import com.eascs.common.util.UuidUtil;
import com.eascs.crm.common.custnew.entity.CustomerEntity;
import com.eascs.crm.common.custnew.service.CustomerService;
import com.eascs.notify.email.EmailSender;
import com.eascs.notify.email.entity.EmailContentEntity;
import com.eascs.notify.email.entity.EmailSourceSetting;
import com.eascs.notify.mail.MailNotifier;
import com.eascs.notify.mail.MailNotifyRequest;
import com.eascs.notify.mail.MailNotifyResponse;
import com.eascs.notify.mail.MailSendType;
import com.eascs.web.o2o.report.constants.FefundConstants;
import com.eascs.web.o2o.scheduler.dao.CrmDao;
import com.eascs.web.o2o.scheduler.dao.WorkflowDao;
import com.eascs.web.o2o.scheduler.entity.AccountLog;
import com.eascs.web.o2o.scheduler.entity.AccountVo;
import com.eascs.web.o2o.scheduler.entity.MongoLogoEntity;
import com.eascs.web.o2o.scheduler.util.Constant;
import com.eascs.workflow.common.vo.ModelResult;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import java.io.StringWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName: PersonalAccountService
 * @Description: 个人系统跑批任务
 * @author 张庆奇
 * @date 2017年11月28日 上午10:25:46
 * @version V1.0
 */
@Service
public class PersonalAccountService {

	protected final Logger logger = LoggerFactory.getLogger(getClass());
	@Inject
	CrmDao crmDao;
	@Reference
	IAccountService accountService;
	@Reference
	CustomerService customerService;
	@Inject
	MongoSchedulService mongoSchedulService;
	@Autowired
	EmailSourceSetting emailSourceSetting;
	@Autowired
	private EmailSender emailSender;
	@Inject
	WorkflowDao workflowDao;
	@Reference
	MailNotifier mailNotifier;

	/**
	 * @Title: createPersonalAccount
	 * @Description: 创建个人账户
	 * @author 张庆奇
	 * @return void
	 * @throws @date
	 *             2017年11月28日 上午9:25:59
	 */
	public void createPersonalAccount() {

		String sql = "select * from account_log where status in(0,2) order by res_time desc";
		int index = 0;
		int total = 0;
		while (true) {
			SqlPageQuery<AccountLog> sqlPageQuery = new SqlPageQuery<>(AccountLog.class, Constant.PROCESS_DATA_LIMIT,
					index, sql);
			PageResult<AccountLog> pageResult = this.crmDao.findDataWithPageForMysql(sqlPageQuery);
			if (pageResult.getReturnDataSize() == 0)
				return;

			for (int i = 0; i < pageResult.getReturnDataSize(); i++) {
				AccountLog accountLog = pageResult.getData().get(i);
				
				CreateAccountParamVO vo = new CreateAccountParamVO();
				vo.setBizId(accountLog.getCustomerId());
				vo.setRequestId(accountLog.getId());
				vo.setCustomerName(accountLog.getCustomerName());
				vo.setAccountType(AccountType.INDIVIDUAL);
				vo.setSource(SourceType.WEB);
				logger.info("total:{},{}", ++total, accountLog);
				ModelResult<String> result = new ModelResult<String>();
				Date startTime = null;
				Date endTime = null;

				try {
					startTime = new Date();
					// 1.调用账户系统接口创建个人账户
					result = accountService.createAccount(vo);
					
				} catch (Exception e) {
					logger.error("用户ID", accountLog.getCustomerId());
					logger.error("调用账户系统创建个人账户出错", e);

				} finally {
					endTime = new Date();
					String repMsg = "";
					String msg = "";
					int status;
					MongoLogoEntity mongoLogoEntity = new MongoLogoEntity();
					mongoLogoEntity.setPageAndClassName(this.getClass().getName());
					if (result.isSuccess()) {
						
						String accountId = result.getModel();
						logger.info("创建个人账户任务成功了,账户id:{}",accountId);
						// 2.调用成功后更新crm客户表(成功后调用)
						customerService.updateCustomerAccountId(accountLog.getCustomerId(), accountId);
						status = 1;
						repMsg = "请求成功";
						msg="成功" ;
					} else {
						status = 2;
						repMsg = result.getErrMsg();
						msg="失败" ;
						// 3. 调用失败后发送邮件
					  CustomerEntity	entity=customerService.queryCustomerEntityByCustomerId(accountLog.getCustomerId());
						AccountVo contentVo = new AccountVo();
						contentVo.setCustomerName(accountLog.getCustomerName());
						contentVo.setCreateTime(endTime);
						contentVo.setStatus(msg);
						contentVo.setIdNum(entity.getIdNumber());
						contentVo.setTitle("生产创建个人账户失败通知");
						RuntimeSetting runtimeSetting = RuntimeSetting.get();
						if(runtimeSetting.getEnv().equals(FefundConstants.ENV_PROD)){
							sendEmail(contentVo);
						}
						
					}
					mongoLogoEntity.setStatus(String.valueOf(status));
					mongoLogoEntity.setResponseInfo(repMsg);
					mongoLogoEntity.setStartTime(startTime);
					mongoLogoEntity.setEndTime(endTime);
					mongoLogoEntity.setRequestInfo(JSON.toJSONString(mongoLogoEntity));
					// 4.向业务系统记录日志(不论成功失败都调用)
					mongoSchedulService.insert(mongoLogoEntity);
					// 5.更新crm客户系统创建账户日志(不论成功失败都调用)
					com.eascs.crm.common.vo.ModelResult<Boolean> flag=customerService.updateAccountLog(accountLog.getId(), status, repMsg);
					logger.info("更新crm客户系统创建账户日志{}--原因[{}]", msg, repMsg);
				}
			}
			
			if(pageResult.getReturnDataSize() <Constant.PROCESS_DATA_LIMIT) break;
			
		}

	}

	public void sendEmail(AccountVo contentVo) {

		String[] receivers = "zz9547@eascs.com".split(",");
		
		//String[] receivers = {"qingqi.zhang@eascs.com"};
		EmailContentEntity entity = new EmailContentEntity();
		entity.setHost(emailSourceSetting.getHost());
		entity.setUsername(emailSourceSetting.getFrom());
		entity.setPassword(emailSourceSetting.getPassword());
		entity.setFrom(emailSourceSetting.getFrom());
		entity.setSubject("生产创建个人账户失败通知");
		MailNotifyRequest mailNotifyRequest = new MailNotifyRequest();
		mailNotifyRequest.setTitle("生产创建个人账户失败通知");
		mailNotifyRequest.setSystemCode("账户系统");
		mailNotifyRequest.setMailSendType(MailSendType.INSTANT);
		mailNotifyRequest.setRequestId(UuidUtil.generateShortUuid());
		mailNotifyRequest.setRequestDateTime(new Date());
		mailNotifyRequest.setBizCode("个人账户创建");
		String content = convertEmailContent(contentVo);
		mailNotifyRequest.setContent(content);
		entity.setContent(content);
		for (String receiver : receivers) {
			entity.setTo(receiver);
			emailSender.send(entity);// 发邮件

			com.eascs.notify.constant.ModelResult<MailNotifyResponse> model = null;

			mailNotifyRequest.setRecipientTo(receiver);
			
			try {
				 	model = mailNotifier.notify(mailNotifyRequest);
				if (model.isSuccess()) {
					workflowDao.excuteSql("update wf_email set status = 1 where request_id = ?",
							model.getModel().getResponseId());
				}
			} catch (Exception e) {
				logger.error("邮件发送接口调用异常", e.getMessage());
				e.printStackTrace();
			}

		}

	}
	
	/**
	 * @Title: convertEmailContent
	 * @Description:封装发送邮件模板
	 * @author 张庆奇
	 * @param vo
	 * @return
	 * @return String
	 * @throws @date
	 *             2017年3月9日 下午2:07:49
	 */
	private String convertEmailContent(AccountVo vo) {
		// 通过指定模板名获取FreeMarker模板实例
		try {
			Configuration configuration = new Configuration(Configuration.VERSION_2_3_24);
			configuration.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "/email/"));
			Template template = configuration.getTemplate("dcEmailTemplate.ftl");
			StringWriter stringWriter = new StringWriter();
			// FreeMarker通过Map传递动态数据
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("email", vo);
			template.process(map, stringWriter);
			String htmlText = stringWriter.toString();
			return htmlText;
		} catch (Exception e) {
			logger.error("生成邮件模板失败", e);
		}
		return null;
	}

}
